package com.aaa.sso.shiro;

import com.aaa.common.entity.Member;
import com.aaa.sso.service.RemoteMemberService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;

public class MemberRealm extends AuthorizingRealm {
    private static final Logger log = LoggerFactory.getLogger(MemberRealm.class);

    @Resource
    private RemoteMemberService remoteMemberService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 若需要权限控制，需实现此方法，当前返回null不影响认证功能
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 1. 获取用户名
        String userName = (String) authenticationToken.getPrincipal();
        if (userName == null || userName.trim().isEmpty()) {
            throw new RuntimeException("用户名不能为空");
        }

        // 2. 查询用户信息
        Member member = remoteMemberService.queryByUserName(userName);
        if (member == null) {
            log.info("用户【{}】不存在", userName);
            throw new UnknownAccountException("用户名或密码错误"); // 更标准的异常类型
        }

        // 3. 校验密码和盐值非空（核心修复点）
        String password = member.getPassword();
        String salt = member.getSalt();

        if (password == null || password.trim().isEmpty()) {
            log.error("用户【{}】的密码为空，请检查数据", userName);
            throw new CredentialsException("用户信息异常，请联系管理员");
        }
        if (salt == null || salt.trim().isEmpty()) {
            log.error("用户【{}】的盐值为空，请检查数据", userName);
            throw new CredentialsException("用户信息异常，请联系管理员");
        }

        // 4. 构建认证信息（此时salt和password必为非空，避免空指针）
        return new SimpleAuthenticationInfo(
                member,          // 身份标识（建议用member.getUsername()更安全）
                password,        // 数据库存储的密码
                ByteSource.Util.bytes(salt),  // 盐值（已确保非空）
                this.getName()
        );
    }

    @Override
    public String getName() {
        return "MemberRealm";
    }
}
